package com.dimples.dd.common.exception;


import com.dimples.dd.common.core.IMsgCode;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.io.Serializable;

/**
 * 错误码对象
 * <p>
 * 业务异常错误码，占用 [0 00 000, +∞)，参见 {@link ServiceErrorCodeRange}
 * <p>
 * TODO 错误码设计成对象的原因，为未来的 i18 国际化做准备
 */
@ToString
@AllArgsConstructor
@NoArgsConstructor
public enum ErrorCode implements IMsgCode, Serializable {

    // ========== 用户模块 A-01-001 ==========
    USER_NOT_EXISTS("A01001", "用户不存在"),
    USER_USERNAME_EXISTS("A01002", "用户账号已经存在"),
    USER_MOBILE_EXISTS("A01003", "手机号已经存在"),
    USER_EMAIL_EXISTS("A01004", "邮箱已经存在"),

    // ========== 角色模块 A-02-001 ==========
    ROLE_ADMIN_CODE_ERROR("A02001", "编码【{}】不能使用"),
    ROLE_NAME_DUPLICATE("A02002", "已经存在名为【{}】的角色"),
    ROLE_CODE_DUPLICATE("A02003", "已经存在编码为【{}】的角色"),
    ROLE_NOT_EXISTS("A02004", "角色不存在"),
    ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE("A02005", "不能操作类型为系统内置的角色"),
    ROLE_IS_BOUND("A02006", "角色【{}】已分配用户，请先解除关联后删除"),

    // ========== 菜单模块 A-03-001 ==========
    MENU_PARENT_ERROR("A03001", "不能设置自己为父菜单"),
    MENU_PARENT_NOT_EXISTS("A03002", "父菜单不存在"),
    MENU_PARENT_NOT_DIR_OR_MENU("A03003", "父菜单的类型必须是目录或者菜单"),
    MENU_NAME_DUPLICATE("A03004", "已经存在该名字的菜单"),
    MENU_NOT_EXISTS("A03005", "菜单不存在"),
    MENU_EXISTS_CHILDREN("A03006", "存在子菜单, 无法删除"),
    ROUTE_NAME_NOT_EXISTS("A03007", "菜单路由名称【{}】不存在"),


    // ========== 机构部门模块 A-04-001 ==========
    DEPT_NOT_FOUND("A04001", "当前部门不存在"),
    DEPT_NOT_ENABLE("A04002", "部门({})不处于开启状态，不允许选择"),
    DEPT_NAME_DUPLICATE("A04003", "已经存在该名字的部门"),
    DEPT_PARENT_NOT_EXITS("A04004", "父级部门不存在"),
    DEPT_EXITS_CHILDREN("A04006", "存在子部门，无法删除"),
    DEPT_PARENT_ERROR("A04007", "不能设置自己为父部门"),
    DEPT_EXISTS_USER("A04008", "部门中存在员工，无法删除"),
    DEPT_PARENT_IS_CHILD("A04010", "不能设置自己的子部门为父部门"),
    ORG_NOT_FOUND("A04101", "当前机构不存在"),
    ORG_NAME_NOT_UNIQUE("A04101", "当前机构名称[{}]已存在"),
    ORG_NAME_UNIQUE("A04102", "当前机构名称[{}]不存在"),
    ORG_CODE_NOT_UNIQUE("A04103", "当前机构代码[{}]已存在"),
    ORG_CODE_UNIQUE("A04104", "当前机构代码[{}]不存在"),
    ORG_NAME_DUPLICATE("A04105", "已经存在该名字的机构"),
    ORG_PARENT_ERROR("A04006", "不能设置自己为父机构"),
    ORG_PARENT_NOT_EXITS("A04107", "父级机构不存在"),
    ORG_EXITS_CHILDREN("A04108", "机构id[{}]存在子机构，无法删除"),
    ORG_PARENT_IS_CHILD("A04119", "不能设置自己的子机构为父机构"),


    // ========== 字典类型 A-06-001 ==========
    DICT_TYPE_NOT_EXISTS("A06001", "当前字典类型【{}】不存在"),
    DICT_TYPE_NOT_ENABLE("A06002", "字典类型不处于开启状态，不允许选择"),
    DICT_TYPE_NAME_DUPLICATE("A06003", "已经存在该名字的字典类型"),
    DICT_TYPE_TYPE_DUPLICATE("A06004", "已经存在该类型的字典类型"),
    DICT_TYPE_HAS_CHILDREN("A06005", "无法删除，字典类型【{}】还有字典数据"),

    // ========== 字典数据 A-07-001 ==========
    DICT_DATA_NOT_EXISTS("A07001", "当前字典数据不存在"),
    DICT_DATA_NOT_ENABLE("A07002", "字典数据({})不处于开启状态，不允许选择"),
    DICT_DATA_VALUE_DUPLICATE("A07003", "已经存在该值的字典数据"),

    // ========== 岗位模块 A-08-001 ==========
    POST_NOT_FOUND("A08001", "当前岗位不存在"),
    POST_NOT_ENABLE("A08002", "岗位({}) 不处于开启状态，不允许选择"),
    POST_NAME_DUPLICATE("A08003", "已经存在该名字的岗位"),
    POST_CODE_DUPLICATE("A08004", "已经存在该标识的岗位"),

    // ========== OAuth2 客户端 A-09-001 =========
    OAUTH2_CLIENT_NOT_EXISTS("A09001", "OAuth2 客户端【id = {}】不存在"),
    OAUTH2_CLIENT_EXISTS("A09002", "OAuth2 客户端编号已存在"),
    OAUTH2_CLIENT_DISABLE("A09003", "OAuth2 客户端已禁用"),
    OAUTH2_CLIENT_AUTHORIZED_GRANT_TYPE_NOT_EXISTS("A09004", "不支持该授权类型"),
    OAUTH2_CLIENT_SCOPE_OVER("A09005", "授权范围过大"),
    OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH("A09006", "无效 redirect_uri: {}"),
    OAUTH2_CLIENT_CLIENT_SECRET_ERROR("A09007", "无效 client_secret: {}"),

    // ========= 文件相关 A-10-001 =================
    FILE_PATH_EXISTS("A10001", "文件路径已存在"),
    FILE_NOT_EXISTS("A10002", "文件不存在"),
    FILE_IS_EMPTY("A10003", "文件为空"),

    // ========== 文件配置 A-11-001 ==========
    FILE_CONFIG_NOT_EXISTS("A11001", "文件配置不存在"),
    FILE_CONFIG_DELETE_FAIL_MASTER("A11002", "该文件配置不允许删除，原因：它是主配置，删除会导致无法上传文件"),

    // ========== 数据源配置 A-12-001 ==========
    DATA_SOURCE_CONFIG_NOT_EXISTS("A12001", "数据源配置 id in 【{}】 不存在"),
    DATA_SOURCE_CONFIG_CODE_EXISTS("A12002", "数据 code: {} 已存在"),
    DATA_SOURCE_CONFIG_NOT_OK("A12003", "数据源配置不正确，无法进行连接, 【{}】"),

    // ========== 短信渠道 A-13-001 ==========
    SMS_CHANNEL_NOT_EXISTS("A-13-001", "短信渠道不存在"),
    SMS_CHANNEL_DISABLE("A-13-002", "短信渠道不处于开启状态，不允许选择"),
    SMS_CHANNEL_HAS_CHILDREN("A-13-003", "无法删除，该短信渠道还有短信模板"),

    // ========== 短信模板 A-14-001 ==========
    SMS_TEMPLATE_NOT_EXISTS("A-14-001", "短信模板【{}】不存在"),
    SMS_TEMPLATE_CODE_DUPLICATE("A-14-002", "已经存在编码为【{}】的短信模板"),
    SMS_TEMPLATE_API_ERROR("A-14-003", "短信 API 模板调用失败，原因是：{}"),
    SMS_TEMPLATE_API_AUDIT_CHECKING("A-14-004", "短信 API 模版无法使用，原因：审批中"),
    SMS_TEMPLATE_API_AUDIT_FAIL("A-14-005", "短信 API 模版无法使用，原因：审批不通过，{}"),
    SMS_TEMPLATE_API_NOT_FOUND("A-14-006", "短信 API 模版无法使用，原因：模版不存在"),

    // ========== 短信发送 A-15-001 ==========
    SMS_SEND_MOBILE_NOT_EXISTS("A-15-001", "手机号不存在"),
    SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS("A-15-002", "模板参数({})缺失"),
    SMS_SEND_TEMPLATE_NOT_EXISTS("A-15-003", "短信模板不存在"),

    // ========== 短信验证码 A-16-001 ==========
    SMS_CODE_NOT_FOUND("A-16-001", "验证码不存在"),
    SMS_CODE_EXPIRED("A-16-002", "验证码已过期"),
    SMS_CODE_USED("A-16-003", "验证码已使用"),
    SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY("A-16-004", "超过每日短信发送数量"),
    SMS_CODE_SEND_TOO_FAST("A-16-005", "短信发送过于频繁"),

    // ========== 站内信模版 A-17-000 ==========
    NOTICE_NOT_FOUND("A-17-000", "当前通知公告不存在"),
    NOTICE_PUSH_USER_NOT_NULL("A-17-001", "推送指定用户不能为空"),
    NOTICE_PUBLISHED("A-17-003", "当前通知公告已发布"),
    NOTICE_PUBLISHED_OR_REVOKE("A-17-004", "通知公告未发布或已撤回"),
    NOTIFY_TEMPLATE_NOT_EXISTS("A-17-001", "站内信模版【{}】不存在"),
    NOTIFY_TEMPLATE_CODE_DUPLICATE ("A-17-002", "已经存在编码为【{}】的站内信模板"),
    NOTIFY_SEND_TEMPLATE_PARAM_MISS("A-17-003", "模板参数({})缺失"),

    // ========== 网关模块 B-01-001 ==========
    GATEWAY_ROUTE_EXISTS("B01001", "路由【{}】已存在"),
    GATEWAY_ROUTE_NOT_EXISTS("B01001", "路由【{}】不存在"),

    // ========== 调度中心模块 C-01-001 ==========
    JOB_LOG_CLEAN_TYPE_UN_VALID("C01001", "清理类型参数异常"),

    ;

    @Override
    public String getCode() {
        return code;
    }

    @Override
    public String getMsg() {
        return msg;
    }

    private String code;

    private String msg;

}
